home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / nfsmount / RCS / nfsLookup.c,v < prev    next >
Text File  |  1991-10-20  |  24KB  |  855 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     91.10.20.12.38.28;  author mottsmth;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     89.10.10.13.17.24;  author douglis;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     89.09.12.14.32.44;  author shirriff;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     88.11.14.15.15.06;  author brent;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     88.11.02.12.44.18;  author brent;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @The main NFS lookup loop.
  37. @
  38.  
  39.  
  40. 1.5
  41. log
  42. @Add remote mount points to support the mounting
  43. of one NFS filesystem within another.
  44. @
  45. text
  46. @/*
  47.  * nfsLookup.c --
  48.  * 
  49.  *    The main NFS pathname lookup procedure.  NFS does lookup component
  50.  *    at a time, while the Sprite interface is based on complete relative
  51.  *    names.  The NfsLookup procedure takes care of chopping the relative
  52.  *    name into components and doing NFS calls to get the handle for
  53.  *    each successive component.
  54.  *
  55.  * Copyright 1988 Regents of the University of California
  56.  * Permission to use, copy, modify, and distribute this
  57.  * software and its documentation for any purpose and without
  58.  * fee is hereby granted, provided that the above copyright
  59.  * notice appear in all copies.  The University of California
  60.  * makes no representations about the suitability of this
  61.  * software for any purpose.  It is provided "as is" without
  62.  * express or implied warranty.
  63.  */
  64. #ifndef lint
  65. static char rcsid[] = "$Header: /sprite/src/cmds/nfsmount/RCS/nfsLookup.c,v 1.4 89/10/10 13:17:24 douglis Exp Locker: mottsmth $ SPRITE (Berkeley)";
  66. #endif not lint
  67.  
  68. #include "stdio.h"
  69.  
  70. #include "nfs.h"
  71. #include "sys/time.h"
  72. #include "sys/stat.h"
  73.  
  74. #include "kernel/fs.h"
  75.  
  76. static int ExpandLink();
  77. static void LookupCacheInsert();
  78. static int CheckMountPoint();
  79.  
  80. NfsReadTest() { return; } ;
  81.  
  82. /*
  83.  * This array holds the names of mount points within our namespace
  84.  * so that we can force redirect lookups. The array is initialized
  85.  * from the command line options using the callback function
  86.  * NfsRecordMountPointProc.
  87.  */
  88. #define MAXMOUNTPOINTS 10
  89.  
  90. typedef struct RedirectNode {
  91.     char *local;              /* Name (relative) in this filesystem */
  92.     char *remote;             /* Name (absolute) where subtree is mounted */
  93. } RedirectNode;
  94.  
  95. static RedirectNode redirectList[MAXMOUNTPOINTS];
  96. static int redirectCount = 0;
  97.  
  98.  
  99. /*
  100.  *----------------------------------------------------------------------
  101.  *
  102.  * NfsLookupTest --
  103.  *
  104.  *    Stub on top of NfsLookup to call it and exercise it.
  105.  * 
  106.  * Results:
  107.  *    None.
  108.  *
  109.  * Side effects:
  110.  *    Prints out the returned attributes of the file.
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114. void
  115. NfsLookupTest(private, name)
  116.     ClientData private;
  117.     char *name;
  118. {
  119.     NfsState *nfsPtr = (NfsState *)private;
  120.     diropokres dirResults;
  121.     diropargs dirArgs;
  122.     diropargs *dirArgsPtr = &dirArgs;
  123.     fattr *attrPtr = &dirResults.attributes;
  124.     int status;
  125.     char component[NFS_MAXNAMLEN];
  126.     Fs_RedirectInfo redirectInfo;
  127.  
  128.     dirArgs.name = component;
  129.     status = NfsLookup(nfsPtr, NULL , name, FS_FOLLOW,
  130.                &dirResults, &dirArgsPtr, &redirectInfo);
  131.     if (status == EREMOTE) {
  132.     printf("REDIRECT => \"%s\"\n", redirectInfo.fileName);
  133.     } else if (status == 0) {
  134.     register int *intPtr;
  135.  
  136.     printf("Handle of %s:%s/%s\n\t", nfsPtr->host, nfsPtr->nfsName, name);
  137.     NfsHandlePrint(&dirResults.file);
  138.     printf("\n");
  139.     printf("Parent handle\n\t");
  140.     NfsHandlePrint(&dirArgsPtr->dir);
  141.     printf("\n");
  142.  
  143.     printf("Attributes of %s:%s/%s\n", nfsPtr->host, nfsPtr->nfsName, name);
  144.     printf("\tFileID %x FS_ID %x\n",
  145.         attrPtr->fileid,
  146.         attrPtr->fsid);
  147.     printf("\tType %d mode 0%o links %d size %d\n",
  148.         attrPtr->type,
  149.         attrPtr->mode,
  150.         attrPtr->nlink,
  151.         attrPtr->size);
  152.     } else {
  153.     if (dirArgsPtr != (diropargs *)NULL) {
  154.         printf("Parent of %s\n\t", dirArgsPtr->name);
  155.         NfsHandlePrint(&dirArgsPtr->dir);
  156.         printf("\n");
  157.     }
  158.     printf("Lookup of %s:%s/%s returns <%d>\n",
  159.         nfsPtr->host, nfsPtr->nfsName, name, status);
  160.     }
  161. }
  162.  
  163. /*
  164.  *----------------------------------------------------------------------
  165.  *
  166.  * NfsLookup --
  167.  *
  168.  *    Called to return a nfs_fh for a path inside NFS.  Because NFS only
  169.  *    does component-at-a-time lookup we have to loop through the
  170.  *    pathname ourselves.  This routine is modeled very closely on
  171.  *    the Sprite kernel routine Fs_LocalLookup.
  172.  * 
  173.  * Results:
  174.  *    This returns an error code from NFS, or -1 if NFS access failed
  175.  *    entirely.  Upon NFS_OK return then *dirResultsPtr is filled in
  176.  *    with the handle and attributes for the name looked up.  If
  177.  *    dirArgsPtrPtr is non-null then this indirectly references storage
  178.  *    for the last pathname component and the handle of its parent.
  179.  *    This information is filled in if possible, otherwise the pointer
  180.  *    is cleared to indicate the information isn't available.
  181.  *    EREMOTE is returned if a symbolic link to the root was
  182.  *    encountered, or the pathname left via ".." out the top of the
  183.  *    NFS system.  *redirectInfoPtr gets filled in with the new
  184.  *    pathname in this case.
  185.  *
  186.  * Side effects:
  187.  *    None (yet).
  188.  *
  189.  *----------------------------------------------------------------------
  190.  */
  191. int
  192. NfsLookup(nfsPtr, cwdFilePtr, name, useFlags, dirResultsPtr, dirArgsPtrPtr,
  193.     redirectInfoPtr)
  194.     NfsState *nfsPtr;        /* Top level state for NFS connection */
  195.     NfsOpenFile *cwdFilePtr;    /* Handle for directory at start of path.
  196.                  * If NULL the mount point is used. */
  197.     char *name;            /* Name relative to cwdHandle */
  198.     int useFlags;        /* Sprite Lookup flags.  FS_FOLLOW means
  199.                  * follow symbolic links. */
  200.     diropokres *dirResultsPtr;    /* Return - handle and attributes of name */
  201.     diropargs **dirArgsPtrPtr;    /* If non-NULL **dirArgsPtrPtr is filled in
  202.                  * with the last component of name and the
  203.                  * handle for the parent directory.  This is
  204.                  * used when creating, removing, etc. Note
  205.                  * that (*dirArgsPtrPtr)->name must point
  206.                  * to storage for the pathname component. */
  207.     Fs_RedirectInfo *redirectInfoPtr; /* Returned name if a symbolic link to the
  208.                  * root is encountered.  Return value of
  209.                  * the procedure is EREMOTE in this case. */
  210. {
  211.     register char *curCharPtr;
  212.     register int compLen = -1;
  213.     register char *compPtr;
  214.     register nfs_fh *cwdHandlePtr;
  215.     register int status = (int) NFS_OK;
  216.     int numLinks = 0;
  217.     int haveGoodAttrs = 0;
  218.     diropargs *returnDirArgsPtr;
  219.     diropargs dirArgs;
  220.     diropres dirResults;
  221.     char component[NFS_MAXNAMLEN];
  222.     char expandedPath[NFS_MAXNAMLEN];
  223.     int isMountPoint;
  224.  
  225.     /*
  226.      * Initialize lookup.  Skip leading slashs, get a handle for the
  227.      * current starting point, fill in the diropargs that we'll be
  228.      * passing to the NFS server.
  229.      */
  230.     redirectInfoPtr->prefixLength = 0;        /* no remote links in NFS */
  231.     if (dirArgsPtrPtr != (diropargs **)NULL) {
  232.     returnDirArgsPtr = *dirArgsPtrPtr;
  233.     *dirArgsPtrPtr = (diropargs *)NULL;    /* to indicate no parent, yet */
  234.     } else {
  235.     returnDirArgsPtr = (diropargs *)NULL;
  236.     }
  237.     curCharPtr = name;
  238.     while (*curCharPtr && *curCharPtr == '/') {
  239.     curCharPtr++;
  240.     }
  241.     if (cwdFilePtr == (NfsOpenFile *)NULL) {
  242.     cwdHandlePtr = nfsPtr->mountHandle;
  243.     } else {
  244.     cwdHandlePtr = cwdFilePtr->handlePtr;
  245.     }
  246.     dirArgs.name = component;
  247.     /*
  248.      * Loop through the pathname.
  249.      */
  250.     while (*curCharPtr != '\0') {
  251.     /*
  252.      * Copy the next component and skip trailing slashes.
  253.      */
  254.     compPtr = component;
  255.     while (*curCharPtr != '/' && *curCharPtr != '\0') {
  256.         *compPtr++ = *curCharPtr++;
  257.     }
  258.     compLen = compPtr - component;
  259.     if (compLen >= NFS_MAXNAMLEN) {
  260.         status = NFSERR_NAMETOOLONG;
  261.         goto exit;
  262.     }
  263.     *compPtr = '\0';
  264.     bcopy((char *)cwdHandlePtr, (char *)&dirArgs.dir, sizeof(nfs_fh));
  265.  
  266.     isMountPoint = (bcmp((char *)cwdHandlePtr,
  267.               (char *)nfsPtr->mountHandle,
  268.               NFS_FHSIZE) == 0);
  269.  
  270.     if ((isMountPoint) &&
  271.         (CheckMountPoint(component,redirectInfoPtr->fileName) >= 0)) {
  272.         (void)strcat(redirectInfoPtr->fileName, curCharPtr);
  273.         return(EREMOTE);
  274.     }
  275.  
  276.     while (*curCharPtr == '/') {
  277.         curCharPtr++;
  278.     }
  279.     if (compLen == 2 && component[0] == '.' && component[1] == '.') {
  280.         /*
  281.          * Going to the parent directory, "..".
  282.          */
  283.         if (isMountPoint) {
  284.         /*
  285.          * We are falling off the top of the NFS system.  Copy the
  286.          * remaining part of the name, including the "../", into
  287.          * *newNamePtr and return that, instead of a handle.
  288.          */
  289.         (void)strcpy(redirectInfoPtr->fileName, "../");
  290.         (void)strcat(redirectInfoPtr->fileName, curCharPtr);
  291.         return(EREMOTE);
  292.         }
  293.     } else if (compLen == 1 && component[0] == '.') {
  294.         /*
  295.          * Already have a handle on ".", the current directory.
  296.          */
  297.         continue;
  298.     }
  299.     /*
  300.      * Lookup the next component via NFS.  Remember that the current
  301.      * handle has been copied into dirArgs, and the result handle
  302.      * will be copied into dirResults by the XDR routines.
  303.      */
  304.     if (clnt_call(nfsPtr->nfsClnt, NFSPROC_LOOKUP, xdr_diropargs, &dirArgs,
  305.             xdr_diropres, &dirResults, nfsTimeout) != RPC_SUCCESS) {
  306.         clnt_perror(nfsPtr->nfsClnt, "NfsLookup: RPC nfsproc_lookup_2");
  307.         status = -1;
  308.         goto exit;
  309.     } else if (dirResults.status != NFS_OK) {
  310.         /*
  311.          * Lookup failed.  If we failed on the last component we set up
  312.          * the returned dirArgs so they are useful for a subsequent
  313.          * create.  returnDirArgsPtr is the original pointer to
  314.          * good storage provided by our caller.  We set the pointer
  315.          * to this pointer to indicate the storage now has valid data.
  316.          */
  317.         status = (int)dirResults.status;
  318.         if (*curCharPtr == '\0' && returnDirArgsPtr != (diropargs *)NULL) {
  319.         bcopy((char *)&dirArgs.dir, (char *)&returnDirArgsPtr->dir,
  320.             sizeof(nfs_fh));
  321.         strcpy(returnDirArgsPtr->name, component);
  322.         *dirArgsPtrPtr = returnDirArgsPtr;
  323.         }
  324.         goto exit;
  325.     } else {
  326.         /*
  327.          * Lookup succeeded.  The lookup result is cached for
  328.          * a brief period to optimize heavy traffic through top-level
  329.          * directories.
  330.          */
  331.         haveGoodAttrs = 1;
  332.         cwdHandlePtr = &dirArgs.dir;
  333.         LookupCacheInsert(cwdHandlePtr, component, &dirResults);
  334.  
  335.         if ((*curCharPtr != '\0' || (useFlags & FS_FOLLOW)) &&
  336.         dirResults.diropres_u.diropres.attributes.type == NFLNK) {
  337.         /*
  338.          * Hit a symbolic link in the middle of a pathname or at
  339.          * the end are we are told to follow it.
  340.          */
  341.         numLinks++;
  342.         if (numLinks > FS_MAX_LINKS) {
  343.             status = ELOOP;
  344.             goto exit;
  345.         } else {
  346.             int offset;        /* Distance of existing name from the
  347.                      * start of its buffer */
  348.             if (numLinks == 1) {
  349.             offset = (int)curCharPtr - (int)name;
  350.             } else {
  351.             offset = (int)curCharPtr -
  352.                  (int)(expandedPath);
  353.             }
  354.             status = ExpandLink(nfsPtr, &dirResults, curCharPtr, offset,
  355.                     expandedPath);
  356.             if (status != NFS_OK) {
  357.             goto exit;
  358.             }
  359.             curCharPtr = expandedPath;
  360.         }
  361.         if (*curCharPtr == '/') {
  362.             /*
  363.              * A link back to the root has to be handled by the
  364.              * prefix table in the Sprite kernel.
  365.              */
  366.             strcpy(redirectInfoPtr->fileName, expandedPath);
  367.             return(EREMOTE);
  368.         }
  369.         /*
  370.          * The link was relative so we reset the current handle
  371.          * to point to the same place we found the link.
  372.          */
  373.         cwdHandlePtr = &dirArgs.dir;
  374.          } else {
  375.          /*
  376.           * Not a symbolic link.
  377.           * Advance the current handle to the component we just found.
  378.           */
  379.          cwdHandlePtr = &dirResults.diropres_u.diropres.file;
  380.          }
  381.     }
  382.     }
  383.     /*
  384.      * Lookup complete.  Copy out our results.
  385.      */
  386.     if (haveGoodAttrs) {
  387.     bcopy((char *)&dirResults.diropres_u.diropres, (char *)dirResultsPtr,
  388.         sizeof(diropokres));
  389.     if (returnDirArgsPtr != (diropargs *)NULL) {
  390.         /*
  391.          * Our caller wants information about the parent directory
  392.          * for a delete, rename, or link.  We restore the pointer
  393.          * to indicate that this information has been provided.
  394.          */
  395.         bcopy((char *)&dirArgs.dir, (char *)&returnDirArgsPtr->dir,
  396.             sizeof(nfs_fh));
  397.         strcpy(returnDirArgsPtr->name, component);
  398.         *dirArgsPtrPtr = returnDirArgsPtr;
  399.     }
  400.     } else {
  401.     /*
  402.      * We didn't go throught the lookup loop because our caller asked
  403.      * for an empty name.  We do an explicit get attributes.
  404.      */
  405.     register attrstat *tmpAttrPtr;
  406.     tmpAttrPtr = nfsproc_getattr_2(cwdHandlePtr, nfsPtr->nfsClnt);
  407.     if (tmpAttrPtr == (attrstat *)NULL) {
  408.         clnt_perror(nfsPtr->nfsClnt, "NfsLookup: RPC  nfsproc_getattr_2");
  409.         status = -1;
  410.         goto exit;
  411.     } else if (tmpAttrPtr->status != NFS_OK) {
  412.         status = (int)tmpAttrPtr->status;
  413.         goto exit;
  414.     } else {
  415.         bcopy((char *)cwdHandlePtr, (char *)&dirResultsPtr->file,
  416.             NFS_FHSIZE);
  417.         bcopy((char *)&tmpAttrPtr->attrstat_u.attributes,
  418.           (char *)&dirResultsPtr->attributes, sizeof(fattr));
  419.     }
  420.     }
  421. exit:
  422.     if (status == -1 && errno != 0) {
  423.     status = errno;
  424.     }
  425.     return(status);
  426. }
  427.  
  428. /*
  429.  *----------------------------------------------------------------------
  430.  *
  431.  * LookupCacheInsert --
  432.  *
  433.  *    Tuck away a <nfs_fh, component> => <nfs_fh> mapping.
  434.  * 
  435.  * Results:
  436.  *    None.
  437.  *
  438.  * Side effects:
  439.  *    Adds an entry into the component cache.
  440.  *
  441.  *----------------------------------------------------------------------
  442.  */
  443. static void
  444. LookupCacheInsert(component, dirResultsPtr)
  445.     char *component;        /* Pathname component just looked up. */
  446.     diropres *dirResultsPtr;    /* Return info from NFS server */
  447. {
  448.     return;
  449. }
  450.  
  451. /*
  452.  *----------------------------------------------------------------------
  453.  *
  454.  * ExpandLink --
  455.  *    Expand a link by shifting the remaining pathname over and
  456.  *    inserting the contents of the link file.
  457.  *
  458.  * Results:
  459.  *    None.
  460.  *
  461.  * Side effects:
  462.  *    Expands the link into nameBuffer.
  463.  *
  464.  *----------------------------------------------------------------------
  465.  */
  466. static int
  467. ExpandLink(nfsPtr, dirResultsPtr, curCharPtr, offset, nameBuffer)
  468.     NfsState    *nfsPtr;        /* Needed for ReadLink RPC */
  469.     diropres    *dirResultsPtr;        /* Handle + attrs of the link file */
  470.     char    *curCharPtr;        /* Points to beginning of the remaining
  471.                      * name that has to be shifted */
  472.     int        offset;            /* Offset of curCharPtr within its 
  473.                      * buffer */
  474.     char     nameBuffer[];        /* New buffer for the expanded name */
  475. {
  476.     ReturnStatus     status;
  477.     int         linkNameLength;    /* The length of the name in the
  478.                      * link NOT including the Null */
  479.     readlinkres        readLinkResult;
  480.     char        savedC;
  481.     register char     *srcPtr;
  482.     register char     *dstPtr;
  483.  
  484.     linkNameLength = dirResultsPtr->diropres_u.diropres.attributes.size;
  485.     if (*curCharPtr == '\0') {
  486.     /*
  487.      * There is no pathname to shift around.
  488.      * Make sure the new name is null terminated
  489.      */
  490.     nameBuffer[linkNameLength] = '\0';
  491.     } else {
  492.     /*
  493.      * Set up srcPtr to point to the start of the remaining pathname.
  494.      * Set up dstPtr to point to just after where the link will be,
  495.      * ie. just where the '/' is that separates the link value from
  496.      * the remaining pathname.
  497.      */
  498.     srcPtr = curCharPtr;
  499.     dstPtr = &nameBuffer[linkNameLength];
  500.     if (linkNameLength < offset) {
  501.         /*
  502.          * The remaining name has to be shifted left.
  503.          * For example, /first is a link to /usr (or /users).  With the
  504.          * filename /first/abc, curCharPtr will point to the 'a' in "abc".
  505.          * dstPtr points to the '\0' after "/usr".
  506.          *
  507.          *  / f i r s t / a b c \0        { current name, offset = 7 }
  508.          *  / u s r \0            { link name, len = 4 }
  509.          *  / u s e r s \0            {   or len = 6 }
  510.          *  / u s r / a b c            { final result }
  511.          *
  512.          * Insert the separating '/' first, then start at the beginning
  513.          * of the remaining name and copy it into the new buffer.
  514.          */
  515.         *dstPtr = '/';
  516.         dstPtr++;
  517.         for( ; ; ) {
  518.         *dstPtr = *srcPtr;
  519.             if (*srcPtr == '\0') {
  520.             break;
  521.         }
  522.         dstPtr++;
  523.         srcPtr++;
  524.         }
  525.     } else {
  526.         /*
  527.          * The remaining name has to be shifted right.
  528.          * For example, /first is a link to /usr/tmp.  With the filename
  529.          * /first/abc, curCharPtr will point to the 'a' in "abc".
  530.          * dstPtr points to the '\0' after "/usr/tmp".
  531.          *
  532.          * / f i r s t / a b c \0        { current name, offset = 7 }
  533.          * / u s r / t m p \0        { link name, len = 8 }
  534.          * / u s r / t m p / a b c        { final result }
  535.          * 
  536.          * Zoom to the end of the name (adjusting dstPtr to account
  537.          * for where the '/' will go) and then shift the name right.
  538.          */
  539.         dstPtr++;
  540.         while (*srcPtr != '\0') {
  541.         srcPtr++;
  542.         dstPtr++;
  543.         }
  544.         while (srcPtr >= curCharPtr) {
  545.         *dstPtr = *srcPtr;
  546.         dstPtr--;
  547.         srcPtr--;
  548.         }
  549.         *dstPtr = '/';
  550.     }
  551.     }
  552.     /*
  553.      * Read and insert the link name in front of the remaining name
  554.      * that was just shifted over.  By initializing the character string
  555.      * pointer (data) before the RPC the XDR routines know to use
  556.      * the existing buffer and not allocate a new one.  Also, the XDR routines
  557.      * are going to null terminate the string and stomp on the character
  558.      * after the link value, so we save and restore that.
  559.      */
  560.     readLinkResult.readlinkres_u.data = nameBuffer;
  561.     savedC = nameBuffer[linkNameLength];
  562.     if (clnt_call(nfsPtr->nfsClnt, NFSPROC_READLINK, xdr_nfs_fh,
  563.         &dirResultsPtr->diropres_u.diropres.file, xdr_readlinkres,
  564.         &readLinkResult, nfsTimeout) != RPC_SUCCESS) {
  565.     clnt_perror(nfsPtr->nfsClnt, "nfsproc_lookup_2");
  566.     if (errno != 0) {
  567.         return(errno);
  568.     } else {
  569.         return(-1);
  570.     }
  571.     }
  572.     nameBuffer[linkNameLength] = savedC;
  573.     return(readLinkResult.status);
  574. }
  575.  
  576. /*
  577.  *----------------------------------------------------------------------
  578.  *
  579.  * NfsWriteTest --
  580.  *
  581.  *    Test harness for NFS writing.  This opens a NFS file and copies
  582.  *    a Sprite file to an NFS file.
  583.  * 
  584.  * Results:
  585.  *    None.
  586.  *
  587.  * Side effects:
  588.  *    Prints out the returned attributes of the file.
  589.  *
  590.  *----------------------------------------------------------------------
  591.  */
  592. void
  593. NfsWriteTest(private, spriteName, nfsName)
  594.     ClientData private;
  595.     char *spriteName;
  596.     char *nfsName;
  597. {
  598.     NfsState *nfsPtr = (NfsState *)private;
  599.     diropres longDirResults;
  600.     diropokres *dirResultsPtr = &longDirResults.diropres_u.diropres;
  601.     int status;
  602.     char *newName;
  603.     createargs createArgs;
  604.     diropargs *wherePtr = &createArgs.where;
  605.     sattr *sattrPtr = &createArgs.attributes;
  606.     char component[NFS_MAXNAMLEN];
  607.     Fs_RedirectInfo redirectInfo;
  608.  
  609.     wherePtr->name = component;
  610.     status = NfsLookup(nfsPtr, NULL /* fix */, nfsName,
  611.             FS_FOLLOW, dirResultsPtr, &wherePtr, &redirectInfo);
  612.     if (status == EREMOTE) {
  613.     printf("REDIRECT => \"%s\"\n", redirectInfo.fileName);
  614.     } else if (status == NFSERR_NOENT && wherePtr != (diropargs *)NULL) {
  615.     sattrPtr->mode = 0644;
  616.     sattrPtr->uid = 1020;    /* non-existent! */
  617.     sattrPtr->gid = 94;        /* non-existent! */
  618.     sattrPtr->size = 0;
  619.     sattrPtr->atime.seconds = -1;
  620.     sattrPtr->atime.useconds = -1;
  621.     sattrPtr->mtime.seconds = -1;
  622.     sattrPtr->mtime.useconds = -1;
  623.     if (clnt_call(nfsPtr->nfsClnt, NFSPROC_CREATE, xdr_createargs,
  624.         &createArgs, xdr_diropres, &longDirResults, nfsTimeout)
  625.             != RPC_SUCCESS) {
  626.         clnt_perror(nfsPtr->nfsClnt, "NFSPROC_CREATE");
  627.         return;
  628.     }
  629.     status = longDirResults.status;
  630.     printf("Create of %s:%s/%s returns <%d>\n",
  631.         nfsPtr->host, nfsPtr->nfsName, nfsName, status);
  632.  
  633.     } else {
  634.     printf("Lookup of %s:%s/%s returns <%d>\n",
  635.         nfsPtr->host, nfsPtr->nfsName, nfsName, status);
  636.     }
  637. }
  638.  
  639.  
  640.  
  641. /*
  642.  *----------------------------------------------------------------------
  643.  *
  644.  * NfsRecordMountPointProc --
  645.  *
  646.  *    Add a sub-mount point to our list.
  647.  * 
  648.  *      This routine is called by the Opt_Parse routine when it sees 
  649.  *      a -m option.
  650.  *
  651.  * Results:
  652.  *    None.
  653.  *
  654.  * Side effects:
  655.  *    None.
  656.  *
  657.  * Note:
  658.  *      NFS allows one file system to be mounted within another NFS
  659.  *      namespace.  This causes problems for Sprite since it expects
  660.  *      to have a remote link at each mount point. The kluge of a
  661.  *      solution is to tell nfsmount where the sub-mount points are
  662.  *      in its namespace so that it can return EREMOTE when a lookup
  663.  *      enters one of these subdomains.
  664.  *
  665.  *----------------------------------------------------------------------
  666.  */
  667.  
  668. int
  669. NfsRecordMountPointProc(option, argc, argv)
  670.     char *option;             /* should point to 'm' */
  671.     int argc;                 /* number of remaining args */
  672.     char **argv;              /* arg pointers */
  673. {
  674.     int i;
  675.     struct stat statBuf;
  676.  
  677.     if ((argc < 2) ||
  678.     (*argv[0] == '-') ||
  679.     (*argv[0] == '/') ||
  680.     (*argv[1] != '/')) {
  681.     fprintf(stderr, "Usage -m option: relative-local-name absolute-remote-name\n");
  682.         exit(-1);
  683.     }
  684.  
  685.     if (redirectCount >= MAXMOUNTPOINTS) {
  686.     fprintf(stderr, "Too many mount points specified. (%d max)\n",
  687.         MAXMOUNTPOINTS);
  688.         exit(-1);
  689.     }
  690.  
  691.     if (lstat(argv[1], &statBuf) < 0) {
  692.     perror(argv[1]);
  693.     exit(-1);
  694.     }
  695.  
  696.     if ((statBuf.st_mode & S_IFMT) != S_IFRLNK) {
  697.     fprintf(stderr,"Not a remote link: %s\n", argv[1]);
  698.     exit(-1);
  699.     }
  700.  
  701.     redirectList[redirectCount].local = argv[0];
  702.     redirectList[redirectCount].remote = argv[1];
  703.     redirectCount++;
  704.     
  705.     for (i=0,argc-=2; i<argc; i++) {
  706.     argv[i] = argv[i+2];
  707.     }
  708.  
  709.     /* tell Opt_Parse that we consumed 2 arguments */
  710.     return argc;
  711. }
  712.  
  713. /*
  714.  *----------------------------------------------------------------------
  715.  *
  716.  * CheckMountPoint --
  717.  *
  718.  *    Check a name against the mount point list.
  719.  * 
  720.  * Results:
  721.  *    None.
  722.  *
  723.  * Side effects:
  724.  *    Uses but does not modify the global redirectList.
  725.  *
  726.  *----------------------------------------------------------------------
  727.  */
  728.  
  729. static int
  730. CheckMountPoint(name, redirectPtr)
  731.     char *name;               /* name of local file to verify */
  732.     char *redirectPtr;        /* name to redirect to */
  733. {
  734.     int i;
  735.  
  736.     for (i=0; i<redirectCount; i++) {
  737.     if (strcmp(redirectList[i].local,name) == 0) {
  738.         strcpy(redirectPtr, redirectList[i].remote);
  739.         return i;
  740.     }
  741.     }
  742.  
  743.     return -1;
  744.  
  745. }
  746. @
  747.  
  748.  
  749. 1.4
  750. log
  751. @Changed void * to VoidPtr to remove lint
  752. @
  753. text
  754. @d20 1
  755. a20 1
  756. static char rcsid[] = "$Header: /a/newcmds/nfsmount/RCS/nfsLookup.c,v 1.3 89/09/12 14:32:44 shirriff Exp Locker: douglis $ SPRITE (Berkeley)";
  757. d27 1
  758. d33 1
  759. d36 17
  760. d177 3
  761. d213 2
  762. a214 1
  763.     if (compPtr - component >= NFS_MAXNAMLEN) {
  764. d219 12
  765. a230 1
  766.     compLen = compPtr - component;
  767. a233 2
  768.     bcopy((char *)cwdHandlePtr, (char *)&dirArgs.dir, sizeof(nfs_fh));
  769.  
  770. d238 1
  771. a238 2
  772.         if (bcmp((char *)cwdHandlePtr, (char *)nfsPtr->mountHandle,
  773.             NFS_FHSIZE) == 0) {
  774. d307 1
  775. a307 1
  776.                  (int)(redirectInfoPtr->fileName);
  777. d310 1
  778. a310 1
  779.                     redirectInfoPtr->fileName);
  780. d314 1
  781. a314 1
  782.             curCharPtr = redirectInfoPtr->fileName;
  783. d321 1
  784. d594 107
  785. @
  786.  
  787.  
  788. 1.3
  789. log
  790. @Updated to new Fs_ typedefs
  791. @
  792. text
  793. @d20 1
  794. a20 1
  795. static char rcsid[] = "$Header: /a/newcmds/nfsmount/RCS/nfsLookup.c,v 1.2 88/11/14 15:15:06 brent Exp Locker: shirriff $ SPRITE (Berkeley)";
  796. d151 1
  797. a151 1
  798.     register int status = NFS_OK;
  799. d230 1
  800. a230 1
  801.         clnt_perror(nfsPtr->nfsClnt, "nfsproc_lookup_2");
  802. d331 3
  803. a333 1
  804.         clnt_perror(nfsPtr->nfsClnt, "nfsproc_getattr_2");
  805. d345 3
  806. d489 5
  807. a493 1
  808.     return(-1);
  809. @
  810.  
  811.  
  812. 1.2
  813. log
  814. @Added user authentication
  815. @
  816. text
  817. @d20 1
  818. a20 1
  819. static char rcsid[] = "$Header: /sprite/users/brent/nfstest/RCS/nfsLookup.c,v 1.1 88/11/02 12:44:18 brent Exp $ SPRITE (Berkeley)";
  820. d62 1
  821. a62 1
  822.     FsRedirectInfo redirectInfo;
  823. d107 1
  824. a107 1
  825.  *    the Sprite kernel routine FsLocalLookup.
  826. d143 1
  827. a143 1
  828.     FsRedirectInfo *redirectInfoPtr; /* Returned name if a symbolic link to the
  829. d521 1
  830. a521 1
  831.     FsRedirectInfo redirectInfo;
  832. @
  833.  
  834.  
  835. 1.1
  836. log
  837. @Initial revision
  838. @
  839. text
  840. @d20 1
  841. a20 1
  842. static char rcsid[] = "$Header: fsPfs.c,v 6.0 88/10/11 15:52:49 brent Exp $ SPRITE (Berkeley)";
  843. d128 1
  844. a128 1
  845. NfsLookup(nfsPtr, cwdHandlePtr, name, useFlags, dirResultsPtr, dirArgsPtrPtr,
  846. d131 1
  847. a131 1
  848.     nfs_fh *cwdHandlePtr;    /* Handle for directory at start of path.
  849. d150 1
  850. d174 1
  851. a174 1
  852.     if (cwdHandlePtr == (nfs_fh *)NULL) {
  853. d176 2
  854. @
  855.